using System;
using System.Windows.Forms;
using OhioState.Graphics.Proxy;
using OhioState.Math;


namespace ShapeEditor
{
    public partial class PlaneControl : UserControl
    {
        private Plane sPlane;

        //
        // Delegate for Plane Control
        //
        private delegate void PlaneHandler(Plane SPlane);
        

        public PlaneControl()
        {
            InitializeComponent();
        }

        #region Public Properties
        
        public Plane SPlane
        {
            get { return sPlane; }
        }
        //
        // Set the focus of this control to a new ROI.  Be careful of thread issues
        private void SetPlane_thisThread(Plane SPlane)
        {
            sPlane = null;
            //
            // Toggle Enabled based on whether the SPlane is null or not
            //
            if (SPlane == null)
            {
                this.Enabled = false;
            }
            else
            {
                this.Enabled = true;
                pointX.Value = new Decimal(SPlane.Point[0]);
                pointY.Value = new Decimal(SPlane.Point[1]);
                pointZ.Value = new Decimal(SPlane.Point[2]);
                normalX.Value = new Decimal(SPlane.Normal[0]);
                normalY.Value = new Decimal(SPlane.Normal[1]);
                normalZ.Value = new Decimal(SPlane.Normal[2]);
            }
            sPlane = SPlane;
        }
        //
        // Force the event to get called on the proper thread.  The DataGridView complains if you try
        //  to use it on the wrong thread.
        //
        public void SetPlane(Plane SPlane)
        {
            PlaneHandler newEvent = new PlaneHandler(SetPlane_thisThread);
            object[] args = new object[1];
            args[0] = SPlane;
            //
            // We need to make sure these methods are executed on the correct thread.
            //
            try
            {
                if (this.InvokeRequired)
                    this.Invoke(newEvent, args);
                else
                    newEvent(SPlane);
            }
            catch { }
        }

        

        #endregion

        private void pointX_ValueChanged(object sender, EventArgs e)
        {
            if (sPlane != null)
            {
                sPlane.BeginManipulation();
                float xNew = Decimal.ToSingle(pointX.Value);
                sPlane.Point = new Vector3(xNew, (float)pointY.Value, (float)pointZ.Value);
                sPlane.EndManipulation();
            }
        }

        private void pointY_ValueChanged(object sender, EventArgs e)
        {
            if (sPlane != null)
            {
                sPlane.BeginManipulation();
                float yNew = Decimal.ToSingle(pointY.Value);
                sPlane.Point = new Vector3((float)pointX.Value, yNew, (float)pointZ.Value);
                sPlane.EndManipulation();
            }
        }

        private void pointZ_ValueChanged(object sender, EventArgs e)
        {
            if (sPlane != null)
            {
                sPlane.BeginManipulation();
                float zNew = Decimal.ToSingle(pointZ.Value);
                sPlane.Point = new Vector3((float)pointX.Value, (float)pointY.Value, zNew);
                sPlane.EndManipulation();
            }
        }

        private void normalX_ValueChanged(object sender, EventArgs e)
        {
            if (sPlane != null)
            {
                sPlane.BeginManipulation();
                float xNew = Decimal.ToSingle(normalX.Value);
                sPlane.Normal = new Vector3(xNew, (float)normalY.Value, (float)normalZ.Value);
                sPlane.EndManipulation();
            }

        }

        private void normalY_ValueChanged(object sender, EventArgs e)
        {
            if (sPlane != null)
            {
                sPlane.BeginManipulation();
                float yNew = Decimal.ToSingle(normalY.Value);
                sPlane.Normal = new Vector3((float)normalX.Value, yNew, (float)normalZ.Value);
                sPlane.EndManipulation();
            }
        }

        private void normalZ_ValueChanged(object sender, EventArgs e)
        {
            if (sPlane != null)
            {
                sPlane.BeginManipulation();
                float zNew = Decimal.ToSingle(normalZ.Value);
                sPlane.Normal = new Vector3((float)normalX.Value, (float)normalY.Value, zNew);
                sPlane.EndManipulation();
            }
        }

        public delegate void PlaneVisibility(bool isVisible);

        public void Visibility(bool isVisible)
        {
            PlaneVisibility planeVisibility = new PlaneVisibility(IsVisible_ThisThread);

            object[] args = new object[1];
            args[0] = isVisible;
            //
            // We need to make sure these methods are executed on the correct thread.
            //
            try
            {
                if (this.InvokeRequired)
                    this.Invoke(planeVisibility, args);
                else
                    planeVisibility(isVisible);
            }
            catch { }
            
        }

        public void IsVisible_ThisThread(bool isVisible)
        {
            this.Visible = isVisible;
        }
        
    }
}
